<template>
  <el-card class="box-card">
    <template #header>
      <div class="card-header">
        <span>当前在线列表</span>
        <el-input
          v-model="queryText"
          style="width: 60%"
          placeholder="输入用户名搜索"
          :prefix-icon="Search"
          clearable
        />
      </div>
    </template>
    <el-scrollbar height="400px">
      <div v-for="t in beSearchedUserList" :key="t.id" class="user-item">
        {{ t.ip }}
        <template v-if="t.ip === currentIp">
          <el-tag>你</el-tag>
        </template>
        <template v-else>
          <el-button size="small" @click="handleChallenge(t.ip)" :disabled="t.delay > 0">{{
            t.delay ? t.delay : "PK"
          }}</el-button>
        </template>
      </div>
    </el-scrollbar>
  </el-card>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted, h, watch, computed, getCurrentInstance, defineEmits } from "vue"
import { ElNotification, ElMessage, ElButton, ElLoading } from "element-plus"
import { Search } from "@element-plus/icons-vue"
import { nanoid } from "nanoid"
import io from "socket.io/client-dist/socket.io"
import { createIO } from "@/socket/client"
const IO = createIO(io)

type User = {
  id: string
  ip: string
  delay: number
}

let userList = ref([] as User[])
let queryText = ref("")
let beSearchedUserList = computed(() => {
  return userList.value.filter((u: User) => ~u.ip.indexOf(queryText.value))
})
let currentIp = ref("")

const emit = defineEmits(["goPlaying"])

watch(
  beSearchedUserList,
  newVal => {
    newVal.forEach(t => {
      if (t.delay > 0) {
        setTimeout(() => {
          t.delay--
        }, 1000)
      }
    })
  },
  { deep: true }
)

onMounted(() => {
  IO.on("address", (ip: unknown) => {
    currentIp.value = ip as string
  })

  IO.on("system:users", (users: any) => {
    userList.value = users.map((v: object) => ({
      ...v,
      delay: 0,
    }))
  })

  IO.on("system:notice", (msg: unknown) => {
    // console.log(msg)
    // ElMessage({
    //   showClose: false,
    //   message: msg as string,
    // })
  })

  type challengeMessage = {
    sourceIp: string
    message: string
  }

  IO.on("receive:challenge", (data: challengeMessage) => {
    const El = ElNotification({
      title: "【挑战书】",
      message: h(
        "div",
        {
          style: {
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
          },
        },
        [
          h("div", data.message),
          h(
            "button",
            {
              onClick: () => {
                El.close()
                receiveChallenge(currentIp.value, data.sourceIp)
              },
            },
            "接受"
          ),
        ]
      ),
      duration: 0,
    })
  })

  type playData = {
    data: object
    msg: string
  }

  IO.on("prepare:playing", (data: playData) => {
    const loading = ElLoading.service({
      lock: true,
      text: data.msg,
      background: "rgba(255, 255, 255, 0.85)",
    })

    setTimeout(() => {
      loading.close()
      // 跳转到棋盘页面
      emit("goPlaying", data.data)
    }, 2000)
  })
})

function handleChallenge(ip: string) {
  IO.emit("send:challenge", ip)
  beSearchedUserList.value.some(t => {
    if (t.ip === ip) {
      t.delay = 5
      return true
    }
  })
}

function recursiveReduce() {}

function receiveChallenge(sourceIp: string, targetIp: string) {
  IO.emit("play", { sourceIp, targetIp })
}

function open2() {
  ElNotification({
    title: "Prompt",
    message: "This is a message that does not automatically close",
    duration: 0,
  })
}
</script>

<style scoped lang="scss">
.box-card {
  width: 60vw;
  min-width: 500px;
  max-width: 700px;
}
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;

  span {
    flex: 1;
    font-size: 20px;
  }
}

.user-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px 20px;
  transition: 0.3s;

  &:hover {
    background: rgba(238, 238, 238, 0.534);
  }
}
</style>
